# -*- coding: utf-8 -*-
#

from threading import Thread

from sippeer.framework.service.servicesession import ServiceSession
from sippeer.utils.logutil import logger

from sippeer.libs.pjsip.pjsua import Account, Call, CallCallback
from sippeer.framework.sipsession.siplib import lib



class SIPSessionCallback(CallCallback):
    
    def __init__(self, call=None):
        CallCallback.__init__(self, call)

    # Notification when call state has changed
    def on_state(self):
        global current_call
        print "Call with", self.call.info().remote_uri,
        print "is", self.call.info().state_text,
        print "last code =", self.call.info().last_code, 
        print "(" + self.call.info().last_reason + ")"
        
        if self.call.info().state == pj.CallState.DISCONNECTED:
            current_call = None
            print 'Current call is', current_call

    def on_media_state(self):
        """Notification that the call's media state has changed.

        """
        pass

    def on_dtmf_digit(self, digits):
        """Notification on incoming DTMF digits.

        Keyword argument:
        digits  -- string containing the received digits.

        """
        pass

    def on_transfer_request(self, dst, code):
        """Notification that call is being transfered by remote party. 

        Application can decide to accept/reject transfer request by returning
        code greater than or equal to 500. The default behavior is to accept 
        the transfer by returning 202.

        Keyword arguments:
        dst     -- string containing the destination URI
        code    -- the suggested status code to return to accept the request.

        Return:
        the callback should return 202 to accept the request, or 300-699 to
        reject the request.

        """
        return code

    def on_transfer_status(self, code, reason, final, cont):
        """
        Notification about the status of previous call transfer request. 

        Keyword arguments:
        code    -- SIP status code to indicate completion status.
        text    -- SIP status reason phrase.
        final   -- if True then this is a final status and no further
                   notifications will be sent for this call transfer
                   status.
        cont    -- suggested return value.

        Return:
        If the callback returns false then no further notification will
        be sent for the transfer request for this call.

        """
        return cont

    def on_replace_request(self, code, reason):
        """Notification when incoming INVITE with Replaces header is received. 

        Application may reject the request by returning value greather than
        or equal to 500. The default behavior is to accept the request.

        Keyword arguments:
        code    -- default status code to return
        reason  -- default reason phrase to return

        Return:
        The callback should return (code, reason) tuple.

        """
        return code, reason

    def on_replaced(self, new_call):
        """
        Notification that this call will be replaced with new_call. 
        After this callback is called, this call will be disconnected.

        Keyword arguments:
        new_call    -- the new call that will replace this call.
        """
        pass

    def on_pager(self, mime_type, body):
        """
        Notification that incoming instant message is received on
        this call.

        Keyword arguments:
        mime_type  -- MIME type of the instant message body.
        body       -- the instant message body.

        """
        pass

    def on_pager_status(self, body, im_id, code, reason):
        """
        Notification about the delivery status of previously sent
        instant message.

        Keyword arguments:
        body    -- message body
        im_id   -- message ID
        code    -- SIP status code
        reason  -- SIP reason phrase

        """
        pass

    def on_typing(self, is_typing):
        """
        Notification that remote is typing or stop typing.

        Keyword arguments:
        is_typing -- boolean to indicate whether remote is currently
                     typing an instant message.

        """
        pass

   
    
class SIPSession(Thread):
    """
    """
    
    def __init__(self, call_instance):
        """
        account: Account instance created by lib.create_account() in Account
        """
        Thread.__init__(self)
        
       # self._SIPInstance = account
        self._serviceSessionList = list()
        self._sessionParam = None
        self._sipID = ""
        self._uri = ""
        self._session = call_instance
        
        # peer's uri, ip address, 
        logger.debug("SIPSession::init(): initialize SIPSession")
    
    def setupSession(self, uri):
        self._uri = uri
        
    def getSIPID(self):
        return self._sipID
    
    def serviceSessionRegistry(self, service_session):
        
        if service_session == None:
            logger.error("SIPSession::serviceSessionRegistry(): the registry service session is None ")
            return
        self._serviceSessionList.append(service_session)
        logger.debug("SIPSession::serviceSessionRegistry(): add service session")
        
    def serviceSessionUnregistry(self, service_session):
        
        pass
    
    def run(self):
    
        
        while True:
            pass
    
    def generateServiceSessionID(self):
        """
        Todo: mechanism to generate id for different service
        """
        pass
    
    def getServiceSessionByID(self, session_id):
        
        if len(self._serviceSessionList) == 0:
            logger.debug("SIPSession::getServiceSessionByID(): service session list is NULL")
            return None
        
        i = 0
        while i < len(self._serviceSessionList):
            if self._serviceSessionList[i].getServiceSessionID() == session_id:
                return self._serviceSessionList[i]
            i = i + 1
            
        return None
    
    def test(self):
        print "test sipsession"

            
            
            
        
        